home *** CD-ROM | disk | FTP | other *** search
- //
- // Inventor 2.0 bug fixes that affect correctness of programs that work with
- // Nodekits and Hidden Children.
- //
- // The code in this file fixes problems in the following routines:
- // SoPath::getLength()
- // SoPickedPoint::getMatrix()
- //
- // To get the fixes, compile this file into a .o and then link
- // the .o before -lInventor_s. The linker may give a warning.
- // This is normal and expected.
- //
- // SoPath::getLength() bug:
- // SoPath::getLength and SoPath::getTail can return the wrong answer if the
- // path contains hidden children. This happens if nodes are appended
- // between subsequent calls to getLength or getTail. The returned value can
- // be too large or too far down the path. This error should never cause a
- // core dump because in the worst case returned length will be the full
- // path length and the returned tail will be the tail of the full path.
- // Note that only getLength() needs to be fixed. getTail() will be fixed
- // automatically, since its error occurs only because it gets the wrong
- // answer from getLength.
- //
- // SoPickedPoint::getMatrix bug:
- // SoPickedPoint::getMatrix does a check to see if the given node is the
- // tail of the picked path. If it is the tail, it applies an
- // SoGetMatrixAction to the entire path. If not, it builds a path from the
- // head down to the given node.
- //
- // The method should cast the path to an SoFullPath when looking at the
- // tail, otherwise if there is a nodekit along the path it will be
- // incorrectly applying the action to the full path.
- //
- #include <Inventor/SoPath.h>
- #include <Inventor/SoPickedPoint.h>
- #include <Inventor/actions/SoGetMatrixAction.h>
- #include <Inventor/nodes/SoGroup.h>
-
- int
- SoPath::getLength() const
- {
- // Cast const away...
- SoPath *This = (SoPath *)this;
-
- // If we aren't sure how many are public, figure it out:
- if (numPublic == -1) {
-
- int lastPublicIndex = 0;
- if (minNumPublic > 1)
- lastPublicIndex = minNumPublic - 1;
-
- // Last test is for the second to last node.
- // If it passes, then lastPublicIndex will be incremented to be the
- // final node, which we don't need to test.
-
- for ( ; lastPublicIndex < (getFullLength() - 1) ; lastPublicIndex++) {
- // Children of this node will be private, so stop.
- if ( ! nodes[lastPublicIndex]->isOfType(SoGroup::getClassTypeId()))
- break;
- }
- This->numPublic = This->minNumPublic = lastPublicIndex + 1;
- }
- return numPublic;
- }
-
- void
- SoPickedPoint::getMatrix(SoGetMatrixAction *gma, const SoNode *node) const
- {
- SoPath *xfPath;
-
- // Construct a path from the root down to this node. Use the given
- // path if it's the same
- if (node == NULL || node == ((SoFullPath *)path)->getTail())
- xfPath = path;
-
- else {
- int index = getNodeIndex(node);
- xfPath = path->copy(0, index + 1);
- xfPath->ref();
- }
-
- gma->apply(xfPath);
-
- if (xfPath != path)
- xfPath->unref();
- }
-
-